#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

import os
import json
import argparse
import re
import subprocess
import utils.json_transform

CmgDudePassLib = os.path.abspath("../build/lib/libCmgDudePass.so")
# print(os.path.exists(CmgDudePassLib))
# print(CmgDudePassLib)

def runCompilation(file: str, dir: str, command: str):
    global CmgDudePassLib
    
    ON='-O.'
    CC='/bin/clang\+\+-11|g\+\+'
    C='/bin/clang-11|gcc'
    originalDir = os.getcwd()
    if not os.path.isdir(dir):
        print("json entry: directory is invalid.")
        print("\t",dir)
        exit(1)
    if not os.path.isfile(file):
        print("json entry: file is invalid.")
        print("\t",file)
        exit(1)
    file = os.path.abspath(file)
    dir = os.path.abspath(dir)

    os.chdir(dir)
    tokens = command.split()
    new_tokens = []
    # exec: str
    for token in tokens:
        if re.match(ON,token):
            # print(token)
            # token='-O1'
            new_tokens.append('-O1')
            continue
        if re.match(CC,token):
            # print(token)
            new_tokens.append('clang++-11')
            # exec='clang++-11'
            new_tokens.append('-flto=full')
            new_tokens.append('-fwhole-program-vtables')
            new_tokens.append('-Xclang')
            new_tokens.append('-load')
            new_tokens.append('-Xclang')
            new_tokens.append(CmgDudePassLib)
            continue
        if re.match(C,token):
            # print(token)
            new_tokens.append('clang-11')
            # exec='clang-11'
            new_tokens.append('-flto=full')
            # new_tokens.append('-fwhole-program-vtables')
            new_tokens.append('-Xclang')
            new_tokens.append('-load')
            new_tokens.append('-Xclang')
            new_tokens.append(CmgDudePassLib)
            continue
        # if
        new_tokens.append(token)
    new_command=' '.join(new_tokens)
    print(new_command+'\n')
    p=subprocess.Popen(new_tokens)
    ret=p.wait()
    os.chdir(originalDir)

def main():
    parser = argparse.ArgumentParser(description='Extract compile command from compile_commands.json, delete -ON, add -O1 and load pass plugin.')
    parser.add_argument('-p',type=str,help='Path to directory of compile_commands.json.')
    args = parser.parse_args()
    db = os.path.abspath(os.path.join(args.p,'compile_commands.json'))
    if not os.path.isdir(args.p):
        print('the directory is invalid.')
        exit(1)

    if not os.path.isfile(db):
        print('compile_commands.json does not exist in the directory.')
        exit(1)

    # print(os.getcwd())
    os.chdir(os.path.abspath(args.p))
    # print(os.getcwd())

    with open(db,'r') as f:
        data = json.load(f)
        for entry in data:
            entry=utils.json_transform.bear_json_transform(entry)
            command = entry['command']
            directory = entry['directory']
            file = os.path.join(entry['directory'],entry['file'])
            runCompilation(file,directory,command)


if __name__=='__main__':
    main()